<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      #canvas {
        background-color: black;
        height: 800px;
        width: 800px;
      }
    </style>
  </head>
  <body>
    <div id="canvas"></div>
    <script type="importmap">
      {
        "imports": {
          "three": "../node_modules/three/build/three.module.js",
          "three/addons/": "../node_modules/three/examples/jsm/"
        }
      }
    </script>
    <script type="module">
      import * as THREE from 'three';
      import ThreeBase from './ThreeBase.js';
      import { OrbitControls } from 'three/addons/controls/OrbitControls.js';

      import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js';
      import { RenderPass } from 'three/addons/postprocessing/RenderPass.js';
      import { UnrealBloomPass } from 'three/addons/postprocessing/UnrealBloomPass.js';
      import { OutputPass } from 'three/addons/postprocessing/OutputPass.js';

      class MyThree extends ThreeBase {
        constructor() {
          super();
          this.initCameraPos = [1, 10, 0];
        }
        initCameraAndScence() {
          this.scene = new THREE.Scene();
          let SCREEN_WIDTH = this.container.offsetWidth;
          let SCREEN_HEIGHT = this.container.offsetHeight;

          this.camera = new THREE.PerspectiveCamera(45, SCREEN_WIDTH / SCREEN_HEIGHT, 1, 100);
          this.camera.position.set(...this.initCameraPos);
          this.renderer.setViewport(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
        }
        initThree(container) {
          this.container = container;
          let renderer = new THREE.WebGLRenderer({ antialias: true });
          renderer.setClearColor(0x000000, 0);
          renderer.clear();
          // renderer.toneMapping = THREE.ReinhardToneMapping;
          renderer.setPixelRatio(window.devicePixelRatio);
          renderer.setSize(this.container.offsetWidth, this.container.offsetHeight);
          container.appendChild(renderer.domElement);
          this.renderer = renderer;

          this.initCameraAndScence();

          this.controls = new OrbitControls(this.camera, this.renderer.domElement);
          this.controls.update();
          this.controls.addEventListener('change', this.animateRender.bind(this));

          window.addEventListener('resize', this.onResize.bind(this));
          window.addEventListener('unload', this.cleanAll.bind(this));
        }
        animateRender() {
          this.renderer.setViewport(0, 0, this.container.offsetWidth, this.container.offsetHeight);
          //必须关闭autoClear,避免渲染效果被清除
          this.renderer.autoClear = false;
          this.renderer.clear();
          //不需要发光的物体在bloom后期前隐藏
          this.normalObj.visible = false;

          this.composer.render();
          this.renderer.clearDepth();
          //不需要发光的物体在bloom后期后显示
          this.normalObj.visible = true;
          this.renderer.render(this.scene, this.camera);
        }
        onResize() {
          if (this.container) {
            this.camera.aspect = this.container.offsetWidth / this.container.offsetHeight;
            this.camera.updateProjectionMatrix();
            this.renderer.setSize(this.container.offsetWidth, this.container.offsetHeight);

            this.composer.setSize(this.container.offsetWidth, this.container.offsetHeight);
          }
        }
        createChart(params) {
          const renderScene = new RenderPass(this.scene, this.camera);

          const bloomPass = new UnrealBloomPass(
            new THREE.Vector2(this.container.offsetWidth, this.container.offsetHeight),
            1.5,
            0.4,
            0.85
          );
          bloomPass.threshold = params.threshold;
          bloomPass.strength = params.strength;
          bloomPass.radius = params.radius;

          const composer = new EffectComposer(this.renderer);
          composer.addPass(renderScene);
          composer.addPass(bloomPass);
          const outputPass = new OutputPass();
          composer.addPass(outputPass);

          this.composer = composer;

          this.scene.add(new THREE.AmbientLight(0xcccccc));

          const object = new THREE.Mesh(
            new THREE.BoxGeometry(1, 1, 1),
            new THREE.MeshBasicMaterial({ color: 0xffff00 })
          );
          this.normalObj = object;
          this.scene.add(object);

          const box = new THREE.Mesh(
            new THREE.BoxGeometry(2, 1, 3),
            new THREE.MeshBasicMaterial({ color: 0xff0000 })
          );
          box.position.y = -2;

          this.scene.add(box);
          this.animateRender();
        }
      }

      var myThree = new MyThree();
      window.myThree = myThree;
      myThree.initThree(document.getElementById('canvas'));
      const params = {
        threshold: 0,
        strength: 0.5,
        radius: 0.5,
        exposure: 0.5
      };
      myThree.createChart(params);
    </script>
  </body>
</html>
